package com.sktk.keepAccount.common.web.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * Created by zf on 2016/3/8 0008.
 */
public class CommonUtils {


    public static boolean isNullOrEmpty(Object o) {
        return "".equals(o) || o == null;
    }

    public static String getInviteCodeNumber(int length) {

        StringBuilder inviteCode = new StringBuilder();

        char[] letters = {'2', '3', '4', '5', '6',
                '7', '8', '9', 'A', 'B',
                'C', 'D', 'E', 'F', 'G',
                'H', 'J', 'K', 'L', 'M',
                'N', 'P', 'Q', 'R', 'S',
                'T', 'U', 'V', 'W', 'X', 'Y'};

        Random rd = new Random();

        for (int i = 0; i < length; i++) {
            inviteCode.append(letters[rd.nextInt(31)]);//产生数字0-31的随机数
        }

        return inviteCode.toString();

    }

    public static String getRandomStr(int length) {

        Random rd = new Random();
        String n = "";
        int getNum;
        do {
            getNum = Math.abs(rd.nextInt()) % 10 + 48;//产生数字0-9的随机数
            getNum = Math.abs(rd.nextInt()) % 26 + 97;//产生字母a-z的随机数
            char num1 = (char) getNum;
            String dn = Character.toString(num1);
            n += dn;
        } while (n.length() < length);

        return n;

    }

    public static String getRandomNumber(int length) {

        Random rd = new Random();
        String n = "";
        int getNum;
        do {
            getNum = Math.abs(rd.nextInt()) % 10 + 48;//产生数字0-9的随机数
            char num1 = (char) getNum;
            String dn = Character.toString(num1);
            n += dn;
        } while (n.length() < length);

        return n;

    }

    /**
     * 获取一个区间随机数
     * 该方法作用是生成一个随机的 int 值，该值介于[0,n]的区间，包含0也包含n
     * @param from
     * @param to
     * @return
     */
    public static Integer getRandomNumberByRange(Integer from, Integer to) {
        if (to <= from) {
            return to;
        }
        // Random().nextInt
        // 该方法的作用是生成一个随机的int值，该值介于[0,n)的区间，也就是0到n之间的随机int值，包含0而不包含n。
        return new Random().nextInt((to - from) + 1) + from;
    }

    /**
     * 获取一个区间小数随机数
     * 该方法作用是生成一个随机的 double 值
     * @param min 随机区间最小值
     * @param max 随机区间最大值
     * @param scale 保留几位小数
     * @return
     */
    public static Double getRandomDoubleByRange(Double min, Double max, Integer scale) {

        double result = min + (new Random().nextDouble() * (max - min));

        BigDecimal bigDecimalRes = new BigDecimal(result).setScale(scale, RoundingMode.HALF_UP);

        return Double.parseDouble(String.valueOf(bigDecimalRes));
    }

    public static double formatDouble2(double d) {

        return Double.parseDouble(
                new DecimalFormat("0.00").format(d));

    }

    public static boolean checkArrayJSONValid(String test) {
        try {
            JSONArray.parseArray(test);
        } catch (JSONException ex) {
            return false;
        }
        return true;
    }

    public static boolean checkObjectJSONValid(String test) {
        try {
            JSONObject.parseObject(test);
        } catch (JSONException ex) {
            return false;
        }
        return true;
    }

    /**
     * 判断字符串是否为URL
     *
     * @param urls 需要判断的String类型url
     * @return true:是URL；false:不是URL
     */
    public static boolean isHttpsUrl(String urls) {
        String regex = "(((https)?://)?([a-z0-9]+[.])|(www.))"
                + "\\w+[.|\\/]([a-z0-9]{0,})?[[.]([a-z0-9]{0,})]+((/[\\S&&[^,;\u4E00-\u9FA5]]+)+)?([.][a-z0-9]{0,}+|/?)";//设置正则表达式

        Pattern pat = Pattern.compile(regex.trim());//对比
        Matcher mat = pat.matcher(urls.trim());

        return mat.matches(); //判断是否匹配
    }

    public static Object parseValue(Class<?> parameterTypes, String value) {

        if (value == null || value.trim().length() == 0) {
            return null;
        }
        value = value.trim();

        try {

            if (Byte.class.equals(parameterTypes) || Byte.TYPE.equals(parameterTypes)) {
                return parseByte(value);
            } else if (Boolean.class.equals(parameterTypes) || Boolean.TYPE.equals(parameterTypes)) {
                return parseBoolean(value);
            } else if (String.class.equals(parameterTypes)) {
                return value;
            } else if (Short.class.equals(parameterTypes) || Short.TYPE.equals(parameterTypes)) {
                return parseShort(value);
            } else if (Integer.class.equals(parameterTypes) || Integer.TYPE.equals(parameterTypes)) {
                return parseInt(value);
            } else if (Long.class.equals(parameterTypes) || Long.TYPE.equals(parameterTypes)) {
                return parseLong(value);
            } else if (Float.class.equals(parameterTypes) || Float.TYPE.equals(parameterTypes)) {
                return parseFloat(value);
            } else if (Double.class.equals(parameterTypes) || Double.TYPE.equals(parameterTypes)) {
                return parseDouble(value);
            } else if (Date.class.equals(parameterTypes)) {
                return parseDate(value);
            }

        } catch (RuntimeException e) {
            return null;
        }

        return null;

    }

    private static Byte parseByte(String value) {
        try {
            value = value.replaceAll("　", "");
            return Byte.valueOf(value);
        } catch (NumberFormatException e) {
            throw new RuntimeException("parseByte but input illegal input=" + value, e);
        }
    }

    private static Boolean parseBoolean(String value) {
        value = value.replaceAll("　", "");
        if (Boolean.TRUE.toString().equalsIgnoreCase(value)) {
            return Boolean.TRUE;
        } else if (Boolean.FALSE.toString().equalsIgnoreCase(value)) {
            return Boolean.FALSE;
        } else {
            throw new RuntimeException("parseBoolean but input illegal input=" + value);
        }
    }

    private static Integer parseInt(String value) {
        try {
            value = value.replaceAll("　", "");
            return Integer.valueOf(value);
        } catch (NumberFormatException e) {
            throw new RuntimeException("parseInt but input illegal input=" + value, e);
        }
    }

    private static Short parseShort(String value) {
        try {
            value = value.replaceAll("　", "");
            return Short.valueOf(value);
        } catch (NumberFormatException e) {
            throw new RuntimeException("parseShort but input illegal input=" + value, e);
        }
    }

    private static Long parseLong(String value) {
        try {
            value = value.replaceAll("　", "");
            return Long.valueOf(value);
        } catch (NumberFormatException e) {
            throw new RuntimeException("parseLong but input illegal input=" + value, e);
        }
    }

    private static Float parseFloat(String value) {
        try {
            value = value.replaceAll("　", "");
            return Float.valueOf(value);
        } catch (NumberFormatException e) {
            throw new RuntimeException("parseFloat but input illegal input=" + value, e);
        }
    }

    private static Double parseDouble(String value) {
        try {
            value = value.replaceAll("　", "");
            return Double.valueOf(value);
        } catch (NumberFormatException e) {
            throw new RuntimeException("parseDouble but input illegal input=" + value, e);
        }
    }

    private static Date parseDate(String value) {
        try {
            String datePattern = "yyyy-MM-dd HH:mm:ss";
            SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
            return dateFormat.parse(value);
        } catch (ParseException e) {
            throw new RuntimeException("parseDate but input illegal input=" + value, e);
        }
    }

    public static boolean isNumeric(String str) {
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }


    /**
     * 生成区间内随机数
     * @param min 最小值
     * @param max 最大值
     * @return 区间随机整数
     */
    public static int getRandom(int min, int max) {
        return new Random().ints(min, (max + 1)).limit(1).findFirst().getAsInt();
    }

    /**
     * 比较APP版本号的大小
     * <p>
     * 1、前者大则返回一个正数
     * 2、后者大返回一个负数
     * 3、相等则返回0
     *
     * @param version app版本号
     * @param versionTo to-app版本号
     * @return int
     */
    public static int compareAppVersion(String version, String versionTo) {
        if (version == null || versionTo == null) {
            throw new RuntimeException("版本号不能为空");
        }
        // 注意此处为正则匹配，不能用.
        String[] versionArray = version.split("\\.");
        String[] versionArrayTo = versionTo.split("\\.");
        int idx = 0;
        // 取数组最小长度值
        int minLength = Math.min(versionArray.length, versionArrayTo.length);
        int diff = 0;
        // 先比较长度，再比较字符
        while (idx < minLength
                && (diff = versionArray[idx].length() - versionArrayTo[idx].length()) == 0
                && (diff = versionArray[idx].compareTo(versionArrayTo[idx])) == 0) {
            ++idx;
        }
        // 如果已经分出大小，则直接返回，如果未分出大小，则再比较位数，有子版本的为大
        diff = (diff != 0) ? diff : versionArray.length - versionArrayTo.length;
        return diff;
    }

    /**
     * 在字符串后面追加 0，示例：str 为 1, length 为 4, 则为 "1000"
     *
     * @param str 被处理的字符串
     * @param length 处理之后的位数
     * @return
     */
    public static String numberAfterFillZero(String str, int length) {
        StringBuilder buffer = new StringBuilder(str);
        if (buffer.length() >= length) {
            return buffer.toString();
        } else {
            while (buffer.length() < length) {
                buffer.append("0");
            }
        }
        return buffer.toString();
    }

}
